#ifndef ML_DECISION_STUMP_PREPROCESS_H_
#define ML_DECISION_STUMP_PREPROCESS_H_

#include "WeakLearner.h"

GLOBAL_NAMESPACE_BEGIN
NAMESPACE_MACHINE_LEARNING_BEGIN

class MLDecisionStumpParams;

class MLDecisionStumpPreprocess
{
public:
    MLDecisionStumpPreprocess(int stepNum=10);
    ~MLDecisionStumpPreprocess();

    void reset();
    void setMaxClassNum(int maxClass);
    void setStepNum(int stepNum);
    int  preProcess(const Eigen::MatrixXd& trianData, const Eigen::MatrixXi& labels, const Eigen::MatrixXd& weights);
    void setThresholdCandidate(const std::vector<double>& thresholdCandidates);
    MLDecisionStumpParams* getStump(int classC, int dimF, int threIdx, bool greater);

    int  getClassSize();
    int  getDimensionSize();
    int  getThresholdSize();
    //double getThreshold(int idx);

    int getLabelResponse(MLDecisionStumpParams* stump, const Eigen::RowVectorXi& label);

private:
    void generateThresholds(const Eigen::MatrixXd& trianData);
    void generateParams();
    int  trainOneStump(MLDecisionStumpParams* stump, const Eigen::MatrixXd& trianData, const Eigen::MatrixXi& labels, const Eigen::MatrixXd& weights);

    double getThreshold(int idx, int dim);   // if dim==-1, return thresholdCandidate_[idx]

private:
    std::vector<MLDecisionStumpParams> oneClassStumps_; // data[classC][dimF][threIdx]
    std::vector<double> maxCoeffs_;
    std::vector<double> minCoeffs_;
    std::vector<double> thresholdCandidate_;
    bool                bUseUserDefinedThreshold_;
    int                 stepNum_;
    int                 maxClass_;
    int                 nDim_;
};

NAMESPACE_MACHINE_LEARNING_END
GLOBAL_NAMESPACE_END

#endif//ML_DECISION_STUMP_PREPROCESS_H_